home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Windows Expert
/
Windows Expert.iso
/
windownt
/
sossnt.zip
/
SOSSNT
/
SRC
/
MOUNTD.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-03-03
|
5KB
|
201 lines
/*
* mountd.c --
* Mount daemon program for PC NFS. Runs on top of the net daemon
* (netd.c). This is a partial implementation of the UNIX mount
* daemon mountd(8c).
*
* Author:
* See-Mong Tan, 6/12/88]
*/
#include "common.h"
static void expreply (struct svc_req *, SVCXPRT *);
/*
* bool_t mountd_init() --
* Mount daemon initialization. Creates and registers transport
* handle, and sets exports in the file EXPORTS.
*/
bool_t mountd_init()
{
SOCKET sock;
SOCKADDR_IN local_sin;
SVCXPRT *transp;
sock = socket( PF_INET, SOCK_DGRAM, 0);
if (sock == INVALID_SOCKET) {
(void) fprintf(stderr, "cannot create mountd socket\n");
return FALSE;
}
local_sin.sin_family = AF_INET;
local_sin.sin_port = htons(MOUNTPORT);
local_sin.sin_addr.s_addr = INADDR_ANY;
if (bind( sock,(SOCKADDR *)(&local_sin), sizeof(local_sin)) == SOCKET_ERROR) {
fprintf(stderr,"bind() failed");
return FALSE;
}
if ((transp = svcudp_create(sock, 0, local_sin.sin_port)) == (SVCXPRT *) NULL) {
(void) fprintf (stderr, "mountd: cannot create udp handle");
closesocket(sock);
return FALSE;
}
if (! svc_register(transp, MOUNTPROG, MOUNTVERS, mountd_dispatch,
IPPROTO_UDP)) {
(void) fprintf(stderr, "mountd: cannot register transport\n");
closesocket(sock);
return FALSE;
}
if (! svc_register(transp, MOUNTPROG, MOUNTVERS_OLD, mountd_dispatch,
IPPROTO_UDP)) {
(void) fprintf(stderr, "mountd: warning: cannot register old version\n");
}
if (! exps_parse()) {
(void) fprintf(stderr, "mountd: cannot parse exports file\n");
closesocket(sock);
return FALSE;
}
return TRUE;
}
/*
* void mountd_dispatch(struct svc_req *req, SVCXPRT *xprt) --
* Dispatch routine for the mount daemon.
*/
void mountd_dispatch(req, xprt)
struct svc_req *req;
SVCXPRT *xprt;
{
#if DEBUG
static char *names[] = {"NULL", "MNT", "DUMP", "UMNT", "UMNTALL",
"EXPORT", "EXPORTALL", "<invalid>"};
DBGPRT1 (mountd, ">>> MOUNTPROC_%s", names[(req->rq_proc >
MOUNTPROC_EXPORTALL) ? MOUNTPROC_EXPORTALL+1 : req->rq_proc]);
#endif
switch((int) req->rq_proc) {
case NULLPROC: /* "ping" the mount daemon */
if (! svc_sendreply(xprt, xdr_void, 0)) {
(void) fprintf(stderr, "mountd: cannot send reply\n");
return;
}
break;
case MOUNTPROC_MNT: mount(req, xprt); break;
case MOUNTPROC_UMNT: unmount(req, xprt); break;
case MOUNTPROC_EXPORT: expreply(req, xprt); break;
case MOUNTPROC_DUMP:
case MOUNTPROC_UMNTALL:
case MOUNTPROC_EXPORTALL:
default:
svcerr_noproc(xprt);
}
}
/*
* void mount(struct svc_req *req, SVCXPRT *xprt) --
* Services a mount request
*/
void mount(req, xprt)
struct svc_req *req;
SVCXPRT *xprt;
{
char *path = NULL;
struct fhstatus fhs; /* file handle status */
SOCKADDR_IN local_sin;
if (! svc_getargs(xprt, xdr_path, &path)) {
DBGPRT0 (mountd, "cannot decode mount path");
svcerr_decode(xprt);
return;
}
DBGPRT1 (mountd, "path: %s", path);
local_sin = *(svc_getcaller(xprt));
if (! exps_isclnt(path, local_sin.sin_addr.s_addr)) {
DBGPRT0 (mountd, "access denied");
fhs.fhs_status = NFSERR_ACCES;
}
else if (! mntpntofh(path, &(fhs.fhs_fh))) {
DBGPRT0 (mountd, "illegal path");
fhs.fhs_status = (int) NFSERR_NOENT;
}
else
fhs.fhs_status = (int) NFS_OK;
/* reply to caller */
if (! svc_sendreply(xprt, xdr_fhstatus, &fhs))
(void) fprintf(stderr, "mount: cannot reply to mount req\n");
svc_freeargs(xprt, xdr_path, &path);
}
/*
* void unmount(struct svc_req *req, SVCXPRT *xprt) --
* Unmount a filesystem.
*/
void unmount(req, xprt)
struct svc_req *req;
SVCXPRT *xprt;
{
char *path = NULL;
fhandle_t fh;
if (! svc_getargs(xprt, xdr_path, &path)) {
DBGPRT0 (mountd, "unmount: cannot decode");
svcerr_decode(xprt);
return;
}
DBGPRT1 (mountd, "unmounting %s", path);
if (! mntpntofh(path, &fh))
DBGPRT0 (mountd, "unmount: not in mount list");
if (! svc_sendreply(xprt, xdr_void, NULL)) {
(void) fprintf(stderr, "unmount: cannot send reply\n");
}
svc_freeargs(xprt, xdr_path, &path);
}
/*
* void expreply(struct svc_req *req, SVCXPRT *xprt) --
* Services an exports request
*/
void expreply(req, xprt)
struct svc_req *req;
SVCXPRT *xprt;
{
struct exports *exp_list;
exp_list = exps_get ();
/* reply to caller */
if (! svc_sendreply(xprt, xdr_exports, &exp_list))
(void) fprintf(stderr, "mount: cannot reply to export req\n");
}
/*
* bool_t mntpntofh(char *path, fhandle_t *fhp) --
* Checks that path matches something in the export list and
* converts the path name to file status handle.
*/
bool_t mntpntofh(path, fhp)
char *path;
fhandle_t *fhp;
{
Exports *ptr;
if ((ptr = exps_isexport(path)) == NULL) { /* not in list */
DBGPRT1 (mountd, "path \"%s\" not in export list", path);
return FALSE;
}
/* anything in export list should already be in directory tree cache */
*fhp = pntofh (path);
return TRUE;
}